import TUICore, { TUILogin, TUIConstants } from '@tencentcloud/tui-core';
import TUIChatEngine, { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
import { TUIGlobal } from '@tencentcloud/universal-api';
import { ITUIComponents, ITUIPlugins } from '@/types/interface';
// import TUILocales from './locales';
import { isFunction, isObject } from './utils';
import { isApp } from './utils/env';
import CallkitPluginServer from './plugins/extension-server/callkit';
export default class TUIChatKit {
	static isInitialized : boolean;
	public chat : any;

	public SDKAppID : number;
	public TUICore : any;
	public TUIChatEngine : any;
	public TUIGlobal : any;
	public TUIComponents : ITUIComponents = {};
	public TUIPlugins : ITUIPlugins = {};

	constructor() {
		this.TUICore = TUICore;
		this.TUIChatEngine = TUIChatEngine;
		this.TUIGlobal = TUIGlobal;
		this.SDKAppID = 0;
		this.TUIGlobal._isTIMCallKit = true;
		TUICore.registerEvent(
			TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED,
			TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS,
			this,
		);
	}

	/**
	 * 监听 TUILogin.login 的成功通知
	 * @param { TUIInitParam } params 初始化参数
	 */
	public onNotifyEvent(eventName : string, subKey : string) {
		if (eventName === TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED) {
			switch (subKey) {
				case TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS:
					this.login();
					break;
			}
		}
	}

	/**
	 * init 初始化
	 */
	public init() {
		// 向下兼容，新版本在 index.ts 中默认执行 init 操作
		if (TUIChatKit.isInitialized) {
			return;
		}
		TUIChatKit.isInitialized = true;
		// 原生插件 TUICallKit 存在时执行 call server
		if (isApp) {
			new CallkitPluginServer();
		}
		// TUITranslateService init
		// TUITranslateService.provideLanguages({ ...TUILocales });
		TUITranslateService.useI18n();
		// TUIComponents global install
		TUIGlobal.TUIComponents = this.TUIComponents;
		// TUIPlugins global install
		TUIGlobal.TUIPlugins = this.TUIPlugins;
		console.warn('[TUIChatKit]: init success.');
	}

	/**
	 * login 登录
	 */
	public login() {
		const { chat, SDKAppID, userID, userSig } = TUILogin.getContext();
		this.SDKAppID = SDKAppID;
		this.TUIChatEngine.login({
			chat,
			SDKAppID,
			userID,
			userSig,
		});
		this.chat = chat;
		return this.TUIChatEngine;
	}

	/**
	 * 单个组件挂载
	 *
	 * @param {string} componentName  挂载的组件名
	 * @param {any} component 挂载的组件
	 * @param {any=} env Vue2/Vue3环境
	 * @returns {TUICore} 挂载后的实例
	 */
	public component(componentName : string, component : any, env ?: any) {
		if (this?.TUIComponents?.componentName) {
			console.warn(
				`[TUIChatKit]: ${this?.TUIComponents?.componentName} component has already been applied to target TUIChatEngine.`,
			);
		} else {
			this.TUIComponents[componentName] = component;
			env?.component(componentName, component);
		}
		if (env) {
			!TUIGlobal.Vue && (TUIGlobal.Vue = env);
		}
		return this.TUIChatEngine;
	}

	/**
	 * 组件列表挂载
	 *
	 * @param {object} components 挂载的组件列表
	 * @param {any=} env Vue2/Vue3环境
	 * @returns {TUICore} 挂载后的实例
	 */
	public components(components : object, env ?: any) {
		if (!components || !isObject(components)) {
			console.warn('[TUIChatKit]: components is empty or not object.');
		} else {
			Object?.keys(components)?.forEach((key : string) => {
				this.component(key, components[key as keyof typeof components], env);
			});
		}
		return this.TUIChatEngine;
	}

	/**
	 * 插件注入
	 *
	 * @param {any} TUIPlugin 需要挂载模块的服务
	 * @param {any} options 其他参数
	 * @returns {TUICore} 挂载后的实例
	 */
	public use(TUIPluginName : string, TUIPlugin : any, options ?: any) {
		if (!this.TUICore) {
			console.warn(
				`[TUIChatKit]: Plugin ${this.TUIPlugins[TUIPluginName]} can't be used before init.`,
			);
			return;
		}
		if (this.TUIPlugins[TUIPluginName]) {
			console.warn(
				`[TUIChatKit]: Plugin ${this.TUIPlugins[TUIPluginName]} has already been applied to target TUIChatEngine.`,
			);
		} else if (TUIPlugin && isFunction(TUIPlugin?.plugin)) {
			this.TUIPlugins[TUIPluginName] = TUIPlugin;
			TUIPlugin?.plugin(this, options);
		} else if (isFunction(TUIPlugin)) {
			this.TUIPlugins[TUIPluginName] = TUIPlugin;
			TUIPlugin(this, options);
		} else {
			console.warn(
				'[TUIChatKit]: A plugin must either be a function or an object with an "plugin" '
				+ 'function.'
				+ this.TUIPlugins[TUIPluginName]
				+ 'does not comply with the above rules.',
			);
		}
		return this.TUIChatEngine;
	}
}